v0.3.0: Full Matlab parity — methods, examples, and decoding algorithms#55
Merged
iahncajigas merged 19 commits intomainfrom Mar 11, 2026
Merged
v0.3.0: Full Matlab parity — methods, examples, and decoding algorithms#55iahncajigas merged 19 commits intomainfrom
iahncajigas merged 19 commits intomainfrom
Conversation
Add 19 new static methods to DecodingAlgorithms class, ported from Matlab DecodingAlgorithms.m for v0.3.0 parity: KF_EM family (5 methods): - KF_EMCreateConstraints: Build constraint structures for Kalman EM - KF_EM: Full EM algorithm for linear-Gaussian state-space models - KF_EStep: Forward Kalman filter + RTS smoother - KF_MStep: Parameter updates with diagonal/isotropic constraints - KF_ComputeParamStandardErrors: Fisher information standard errors PP_EM family (5 methods): - PP_EMCreateConstraints: Constraint structures for point-process EM - PP_EM: EM algorithm for point-process state-space models - PP_EStep: Point-process forward filter + backward smoother - PP_MStep: Newton-Raphson updates for mu/beta/gamma parameters - PP_ComputeParamStandardErrors: Standard errors via observed information mPPCO family (9 methods): - mPPCODecode_predict/update: Predict-update cycle for mixed observations - mPPCODecodeLinear: Full linear filter for mixed PP + continuous obs - mPPCO_fixedIntervalSmoother: RTS-style smoother for mPPCO - mPPCO_EMCreateConstraints: Constraint structures for mixed EM - mPPCO_ComputeParamStandardErrors: Standard errors for mixed model - mPPCO_EM/EStep/MStep: Full EM for mixed PP + continuous observations Additional changes: - Add _nearestSPD() helper (Higham 1988 nearest SPD matrix algorithm) - Add _ztest_pvalue() helper for parameter significance testing - Add FitResSummary.plotCoeffsWithoutHistory() and plotHistCoeffs() - Add Trial.toStructure() and Trial.fromStructure() serialization - Add validation lambda computation to Analysis.RunAnalysisForAllNeurons All 180 tests pass. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix readme examples 1-3: use correct kwargs (yunits, dataLabels) instead of invalid (units, labels) for SignalObj/Covariate constructors - Rebuild all 29 Jupyter notebooks from builder scripts to pick up v0.3.0 method additions and code improvements - Execute all notebooks to validate (27/29 pass; 2 pre-existing failures in mEPSCAnalysis and AnalysisExamples2 due to history matrix dimension mismatch, unrelated to v0.3.0 changes) - Regenerate all 24 paper example figures (examples 01-05) - Regenerate readme example images - Regenerate parity report and Sphinx docs All 180 tests pass. All 5 paper examples produce correct outputs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
DecodingAlgorithms: - Add computeSpikeRateCIs: Monte Carlo spike-rate CIs over time window - Add computeSpikeRateDiffCIs: MC CIs for spike-rate difference between windows - Remove 1018-line duplicate SSGLM block (byte-for-byte copy) - Fix nspikeTrain constructor calls (positional arg, not keyword) Trial: - Add getNumHist(): return number of history window coefficients - Add findMinSampleRate(): minimum sample rate across components - Fix getDesignMatrix() dimension mismatch: truncate to min row count when covariate matrix and history matrix have off-by-one time grids SignalObj (15 new methods): - Label utilities: areDataLabelsEmpty, isLabelPresent, convertNamesToIndices - Operators: __matmul__ (mtimes), ldivide, T property (transpose) - Plot props: clearPlotProps, plotPropsSet - Alignment: alignToMax, windowedSignal, normWindowedSignal - Statistics: getSubSignalsWithinNStd - Plotting: plotVariability, plotAllVariability SpikeTrainCollection: - Add reverseOrder parameter to plot() Events: - Add colorString parameter to plot() All 179 tests pass, 2 skipped. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…er, docs - Wire computeValLambda() call in analysis pipeline when validation partition is present (matches Matlab post-fit behaviour) - Filter spike times to [minTime, maxTime] in computeStatistics() so burst metrics remain valid after setMinTime/setMaxTime - Rewrite PPHybridFilter to evaluate CIF objects directly via PPDecode_update (nonlinear CIF support) instead of delegating to PPHybridFilterLinear with extracted linear parameters - Add docstring to kalman_fixedIntervalSmoother documenting the index-extraction approximation vs Matlab's state-augmentation approach - Fix Matplotlib deprecation: boxplot(labels=) → boxplot(tick_labels=) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Implement PPDecodeFilterLinear target estimation branch (Srinivasan 2006): augmented state space with estimateTarget=1, and non-augmented feedforward term with known target yT/PiT. Ports the full Matlab algorithm for goal-directed decoding. - Add FitResult.getHistCoeffsWithLabels() returning (histMat, labels, SEMat) tuple, matching Matlab's multi-output [histMat,labels,SEMat]= getHistCoeffs(). Keep getCoeffs()/getHistCoeffs() returning single arrays for backward compatibility; getCoeffsWithLabels() and getHistCoeffsWithLabels() provide the full tuple form. - Add CovariateCollection.getCovDimension() (Matlab parity). - Fix computeGrangerCausalityMatrix to call tObj.resetEnsCovMask() after completion (Matlab parity cleanup). - Fix plotISIHistogram to honor numBins parameter when specified; defaults to 1ms bin width when numBins is None (matching Matlab). - Update all internal callers of getHistCoeffs/getCoeffs to use appropriate variant (_rawCoeffs, getHistCoeffsWithLabels, etc.). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Matlab's nstCopy constructs the copy with makePlots=0, which triggers computeStatistics. The Python version was passing -1, skipping stats in the constructor. Similarly, setSigRep/setMinTime/setMaxTime were calling computeStatistics(-1) which technically works (computes stats) but is misleading — changed to computeStatistics(0) for clarity. The nstcoll fixture is updated because Python's addSingleSpikeToColl calls nstCopy() (defensive copy, unlike Matlab's reference storage), so both trains now have valid avgFiringRate. This is correct behavior. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Returns combined covariate + history + ensemble labels without mask filtering, matching Matlab's Trial.getAllLabels. This differs from the existing getLabelsFromMask(neuronNum) which applies mask filtering and requires a neuron number. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ixes - psthGLM now computes 1000-draw Monte Carlo confidence intervals on both the PSTH signal and history signal, matching the Matlab implementation. CIs are attached as ConfidenceInterval objects via setConfInterval(). - GLMFit now computes standard errors from the Fisher information matrix (Hessian inverse) and stores them in stats["se"] and stats["covb"]. - SpikeTrainCollection.plot() now accepts selectorArray, minTime, and maxTime parameters matching the Matlab signature. - SpikeTrainCollection.resample() now calls setMinTime/setMaxTime on each train after resampling, matching Matlab behavior for time consistency. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- merge() now calls makeCompatible() to auto-reconcile different time grids instead of raising an error (matching Matlab behavior) - xcov() returns only non-negative lags for auto-covariance (no other arg), matching Matlab's positive-lags-only convention - periodogram() loops over all signal dimensions instead of only the first column, matching the Matlab implementation - MTMspectrum() adds Pval parameter (default 0.95) for chi-squared confidence intervals, multi-dimension support, and returns a 3-tuple (frequencies, psd, ci) matching Matlab's pmtm output Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- normWindowedSignal: use nearest-neighbor interpolation (scipy interp1d
kind='nearest') instead of linear (np.interp), matching Matlab's
interp1(..., 'nearest', 0) behavior.
- getSigRep('zero-mean'): use CI-propagating operator overload (self - mu_cov)
instead of raw NumPy subtraction, so confidence intervals are preserved
through the zero-mean transformation (Matlab: self - self.mu).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add _kalman_filter_matlab() with full Matlab API: time-varying matrices, 6-value return (predicted, updated, gain history, convergence iteration) - Rewrite kalman_fixedIntervalSmoother() using exact augmented-state approach matching Matlab (replaces RTS approximation) - ComputeStimulusCIs: Monte Carlo path for 4-D SSGLM covariance, z-score fallback for 3-D smoother covariance - PPDecode_predict: rcond fallback matching Matlab behavior - Preserve backward-compatible public kalman_filter() API Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…action - KSPlot: pass DTCorrection to FitResult.computeKSStats instead of discarding - plotFitResidual: pass windowSize to FitResult.computeFitResidual - computeHistLag: construct History objects with histMinTimes/histMaxTimes when provided, matching Matlab behavior - computeGrangerCausalityMatrix: extract only the specific neighbor's coefficients from baseline model (fit 1) for phiMat sign computation, matching Matlab's strfind-based label filtering - FitResult._compute_diagnostics: accept dt_correction parameter - FitResult.computeFitResidual: accept windowSize parameter Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- psthGLM: add missing sampleRate multiplier to GLM lambda (trial.py)
- PPSS_EMFB: use backward EM final state xKR[:,-1] for second forward pass
- PPSS_MStep: match Matlab gamma clamping (only >1e2 reduced to 1e1)
- plotSeqCorr/plotInvGausTrans: fix swap — SeqCorr shows U_j vs U_{j+1}
scatter, InvGausTrans shows ACF of gaussianized rescaled ISIs
- plotCoeffs: add error bars (±1 SE) and significance markers
- binCoeffs: per-covariate histograms matching Matlab (returns 2-D array)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… APIs - Rewrite example05 to use PPDecodeFilterLinear and PPHybridFilterLinear instead of OLS linear_decode, with 3 self-contained experiments: univariate sinusoidal decode, 4-D reach PPAF (free vs goal), and hybrid filter with discrete/continuous state estimation - Expand examples 02-04 as self-contained documented scripts matching Matlab counterparts (full workflow, comments, CLI args) - Add goal-directed backward information filter to PPHybridFilterLinear (was previously stubbed out) - Upgrade FitResult.plotResults to Matlab-matching 2x4 subplot layout with 5 diagnostic panels (KS, InvGaus, SeqCorr, Coeffs, Residual) - Fix plotResidual label indexing for multi-fit results - Align all figure filenames to manifest.yml for test compatibility - Add --repo-root CLI arg to examples 03, 04, 05 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Replace manual 2x2 subplot grids with plotResults() calls for Figures 1 and 3, giving the Matlab-matching 2x4 layout with all 5 diagnostic panels (KS, InvGaus, SeqCorr, Coeffs, Residual) - Fix epoch boundary off-by-one: use searchsorted(side='right') to match Matlab's find(time<495,1,'last') inclusive behavior Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Update examples/README.md with current paper example paths and table - Add missing v0.3.0 methods to ClassDefinitions.md: nstColl PSTH/data methods, FitResSummary plotting, DecodingAlgorithms helpers, Trial.getAllLabels - Document goal-directed decoding support in PaperOverview.md for both PPDecodeFilterLinear and PPHybridFilterLinear (Srinivasan et al. 2006) - Add computeSpikeRateCIs and Monte Carlo CI details to PaperOverview.md - Update README.md overview to mention PPAF and PPHF by name Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…psthGLM - Replace 2D pcolormesh with 3D plot_surface for stimulus effect surfaces - Use Poisson link (exp(x)/delta) for Figure 5 true CIF surface, matching Matlab's fitType='poisson' (binomial link still used for Figure 3) - Add fresh psthGLM() call on 50-trial spikeColl for PSTH surface, matching Matlab flow (precomputed data only used for Figure 4 diagnostics) - Remove unused scipy.signal dlti/TransferFunction imports from sim loop Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Change grid from 100x100 to 201x201 (Matlab: meshgrid(-1:0.01:1)) - Add flipud(yy)/fliplr(xx) for Matlab coordinate convention - Use shading='gouraud' to match Matlab's shading interp Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The committed notebook had drifted from the builder output (missing trailing newlines in cells, whitespace differences). Regenerated to match, fixing test_network_tutorial_builder. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
disp/display)Key additions
PPSS_EMFB— Full state-space GLM EM algorithm with forward-backward smoothingPPDecodeFilterLinear/PPHybridFilterLinear— Point-process adaptive and hybrid filterscomputeHistLagForAll— History model-order sweep with logspace windowsSignalObj.MTMspectrum()/spectrogram()/periodogram()— Spectral methodsFitResSummaryplotting:plotAllCoeffs,plot3dCoeffSummary,plotKSSummaryPaper examples
Test plan
--export-figures🤖 Generated with Claude Code